/*
 * If the numbers 1 to 5 are written out in words:
 * one, two, three, four, five, then there are
 * 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
 * 
 * If all the numbers from 1 to 1000 (one thousand)
 * inclusive were written out in words, how many letters would be used?
 * 
 * NOTE: Do not count spaces or hyphens. For example, 342
 * (three hundred and forty-two) contains 23 letters and 115
 * (one hundred and fifteen) contains 20 letters. The use of "and" when
 * writing out numbers is in compliance with British usage.
 */

package pj1;

class Problem16 {
	static final int problem = 1000;

	// for numbers 21-99 -> for completeness
	private static StringBuilder hyphens(Integer number) {
		StringBuilder result = new StringBuilder();
		Integer oneDigit = number % 10;
		Integer twoDigit = number - oneDigit;

		for(NumberWords i : NumberWords.values()) {
			if (i.number().equals(twoDigit)) {
				result.append(i.word());
				break;
			}
		}

		//result.append(NumberWords.HYPHEN.word());

		for(NumberWords i : NumberWords.values()) {
			if (i.number().equals(oneDigit)) {
				result.append(i.word());
				break;
			}
		}

		return result;
	}

	// for numbers >100 -> for correctness in British English
	private static StringBuilder andBE(Integer number) {
		StringBuilder result = new StringBuilder();
		Integer fourDigit = number / 1000;
		Integer threeDigit = number % 1000 / 100;
		Integer twoDigit = number % 100;

		// thousands
		if (fourDigit < 10 && number > 999) {
			for(NumberWords i : NumberWords.values()) {
				if (i.number().equals(fourDigit)) {
					result.append(i.word());
					result.append(NumberWords.THOUSAND.word());
					break;
				}
			}
		}

		// hundreds
		if (threeDigit < 10 && number > 99) {
			for(NumberWords i : NumberWords.values()) {
				if (i.number().equals(threeDigit)) {
					result.append(i.word());
					result.append(NumberWords.HUNDRED.word());
					break;
				}
			}
		}

		// tens
		if (twoDigit > 20 && number > 100) {
			result.append(NumberWords.AND.word());
			result.append(hyphens(twoDigit));
		}
		else if (twoDigit > 20) {
			result.append(hyphens(twoDigit));
		}
		else if (twoDigit.equals(20) && number > 100) {
			result.append(NumberWords.AND.word());
			result.append(NumberWords.TWENTY.word());
		}
		else if (twoDigit.equals(20)) {
			result.append(NumberWords.TWENTY.word());
		}
		else if (number > 100) {
			for(NumberWords i : NumberWords.values()) {
				if (i.number().equals(twoDigit)) {
					result.append(NumberWords.AND.word());
					result.append(i.word());
					break;
				}
			}
		}
		else {
			for(NumberWords i : NumberWords.values()) {
				if (i.number().equals(twoDigit)) {
					result.append(i.word());
					break;
				}
			}
		}
		return result;
	}

	public static void main(String[] args) {
		StringBuilder result = new StringBuilder();
		for (int i = problem; i > 0; i--) {
			result.append(andBE(i));
		}
		System.out.println(result.length());

	}


	// predefine number and words 
	private enum NumberWords {
		ONE("one", 1),
		TWO("two", 2),
		THREE("three", 3),
		FOUR("four", 4),
		FIVE("five", 5),
		SIX("six", 6),
		SEVEN("seven", 7),
		EIGHT("eight", 8),
		NINE("nine", 9),
		TEN("ten", 10),
		ELEVEN("eleven", 11),
		TWELVE("twelve", 12),
		THIRTEEN("thirteen", 13),
		FOURTEEN("fourteen", 14),
		FIFTEEN("fifteen", 15),
		SIXTEEN("sixteen", 16),
		SEVENTEEN("seventeen", 17),
		EIGHTEEN("eighteen", 18),
		NINETEEN("nineteen", 19),
		TWENTY("twenty", 20),
		THIRTY("thirty", 30),
		FOUTY("forty", 40),
		FIFTY("fifty", 50),
		SIXTY("sixty", 60),
		SEVENTY("seventy", 70),
		EIGHTY("eighty", 80),
		NINETY("ninety", 90),
		HUNDRED("hundred", 100),
		THOUSAND("thousand", 1000),
		AND("and", -1),
		SPACE(" ", -1),
		HYPHEN("-", -1);

		NumberWords(String w, Integer n) {
			this.w = w;
			this.n = n;
		}

		private final String w;
		private final Integer n;

		private String word() {
			return w;
		}
		private Integer number() {
			return n;
		}
	}
}
